
package handler.channel;

import anticheat.CheatingOffense;
import client.PureAccount;
import client.PurePlayer;
import client.items.IItem;
import client.items.PureInventoryType;
import client.stats.PlayerStat;
import java.awt.Point;
import packet.creators.MainPacketCreator;
import packet.transfer.read.ReadingPure;
import scripting.EventInstanceManager;
import server.items.InventoryManipulator;
import server.items.ItemInformation;
import server.maps.PureDoor;
import server.maps.PureMapObject;
import server.maps.PureMechDoor;
import server.maps.PureReactor;

public class PlayersHandler {

    public static final void Note(final ReadingPure rh, final PurePlayer chr) {
	final byte type = rh.readByte();

	switch (type) {
	    case 1:
		final byte num = rh.readByte();
		rh.skip(2);

		for (int i = 0; i < num; i++) {
		    final int id = rh.readInt();
		    rh.skip(1);
		    chr.deleteNote(id);
		}
		break;
	    default:
		System.out.println("Unhandled note action, " + type + "");
	}
    }

    public static final void GiveFame(final ReadingPure rh, final PureAccount c, final PurePlayer chr) {
	final int who = rh.readInt();
	final int mode = rh.readByte();

	final int famechange = mode == 0 ? -1 : 1;
	final PurePlayer target = (PurePlayer) chr.getMap().getMapObject(who);

	if (target == chr) { // faming self
	    chr.getCheatTracker().registerOffense(CheatingOffense.FAMING_SELF);
	    return;
	} else if (chr.getLevel() < 15) {
	    chr.getCheatTracker().registerOffense(CheatingOffense.FAMING_UNDER_15);
	    return;
	}
	switch (chr.canGiveFame(target)) {
	    case OK:
		if (Math.abs(target.getFame() + famechange) <= 30000) {
		    target.addFame(famechange);
		    target.updateSingleStat(PlayerStat.FAME, target.getFame());
		}
		if (!chr.isGM()) {
		    chr.hasGivenFame(target);
		}
		c.getSession().write(MainPacketCreator.giveFameResponse(mode, target.getName(), target.getFame()));
		target.getClient().getSession().write(MainPacketCreator.receiveFame(mode, chr.getName()));
		break;
	    case NOT_TODAY:
		c.getSession().write(MainPacketCreator.giveFameErrorResponse(3));
		break;
	    case NOT_THIS_MONTH:
		c.getSession().write(MainPacketCreator.giveFameErrorResponse(4));
		break;
	}
    }

    public static final void UseDoor(final ReadingPure rh, final PurePlayer chr) {
	final int oid = rh.readInt();
        final boolean mode = rh.readByte() == 0; // specifies if backwarp or not, 1 town to target, 0 target to town

        for (PureMapObject obj : chr.getMap().getAllDoor()) {
            final PureDoor door = (PureDoor) obj;
            if (door.getObjectId() == oid) {
                door.warp(chr, mode);
                break;
            }
        }
    }

    public static final void TransformPlayer(final ReadingPure rh, final PureAccount c, final PurePlayer chr) {
	// D9 A4 FD 00
	// 11 00
	// A0 C0 21 00
	// 07 00 64 66 62 64 66 62 64
	rh.skip(4); // Timestamp
	final byte slot = (byte) rh.readShort();
	final int itemId = rh.readInt();
	final String target = rh.readMapleAsciiString().toLowerCase();

	final IItem toUse = c.getPlayer().getInventory(PureInventoryType.USE).getItem(slot);

	if (toUse == null || toUse.getQuantity() < 1 || toUse.getItemId() != itemId) {
	    c.getSession().write(MainPacketCreator.resetActions());
	    return;
	}
	switch (itemId) {
	    case 2212000:
		for (final PurePlayer search_chr : c.getPlayer().getMap().getCharacters()) {
		    if (search_chr.getName().toLowerCase().equals(target)) {
			ItemInformation.getInstance().getItemEffect(2210023).applyTo(search_chr);
			search_chr.dropMessage(6, chr.getName() + " has played a prank on you!");
			InventoryManipulator.removeFromSlot(c, PureInventoryType.USE, slot, (short) 1, false);
		    }
		}
		break;
	}
    }

    public static final void HitReactor(final ReadingPure rh, final PureAccount c) {
	final int oid = rh.readInt();
	final int charPos = rh.readInt();
	final short stance = rh.readShort();
	final PureReactor reactor = c.getPlayer().getMap().getReactorByOid(oid);

	if (reactor == null || !reactor.isAlive()) {
	    return;
	}
        if (c.getPlayer().getMapId() == 240050200) {
            
            EventInstanceManager eim = c.getPlayer().getEventInstance();
            if (reactor.getState() == 0) {
                eim.setProperty("choiceCave", "0");
            } else if (reactor.getState() == 2){
                eim.setProperty("choiceCave", "1");
            } else {
                eim.setProperty("choiceCave", null);
            }
        }
        for (int i = 0; i < reactor.getStats().getStateEventSize(reactor.getState()); i++) {
            reactor.hitReactor(charPos, stance, c, (byte) i);
        } 
    }
    
    public static void UseMechDoor(final ReadingPure rp, final PurePlayer chr) {
        final int oid = rp.readInt();
        final Point pos = rp.readPos();
        final int mode = rp.readByte();
        //chr.getClient().getSession().write(MainPacketCreator.resetActions());
        for (PureMapObject obj : chr.getMap().getAllMechDoor()) {
            final PureMechDoor door = (PureMechDoor) obj;
            if (door.getOwnerId() == oid && door.getId() == mode) {
                //chr.checkFollow();
                chr.getMap().movePlayer(chr, pos);
                break;
            }
        }
        chr.getClient().getSession().write(MainPacketCreator.resetActions());
    }
}
